import datetime
import hashlib
import secrets

import django.utils.timezone as timezone
from django.db import models
from rest_framework import serializers

from common.utils.encrypt import md5
from common.utils.token import create_token
import re

class BaseModel(models.Model):
    """
    基础模型，包含创建时间和更新时间字段
    """
    is_delete = models.IntegerField("数据逻辑状态", choices=((1, "无效"), (0, "有效")), default=0)
    pt_flag = models.IntegerField("压测标志", choices=((1, "压测数据"), (0, "正常数据")), default=0)
    create_time = models.DateTimeField("创建时间", default=timezone.now)
    update_time = models.DateTimeField("更新时间", auto_now=True, null=True, blank=True)

    class Meta:
        abstract = True  # 表示这是一个抽象类，不会生成对应的表
        ordering = ['-create_time']


class BaseSortModel(BaseModel):
    sort_num = models.SmallIntegerField("排序号", default=0)
    CHOICES_STATUS = ((0, "关闭"), (1, "开启"))
    is_active = models.SmallIntegerField("状态", choices=CHOICES_STATUS, default=1)

    class Meta:
        abstract = True
        ordering = ["-create_time"]


class Account(BaseSortModel):
    username = models.CharField('姓名', unique=True, max_length=20, blank=True, null=True, default="")
    password = models.CharField("密码", max_length=128, blank=True, null=True, default="")
    mobile = models.CharField('手机号', max_length=100, blank=True, null=True, default="")
    token = models.CharField("Token", max_length=512, blank=True, null=True, default="")
    openid = models.CharField("openid", max_length=512, blank=True, null=True, default="")
    status = models.IntegerField("状态", choices=((0, "禁用"), (1, "启用")), default=1)
    is_admin = models.IntegerField("管理员类型", choices=((0, "管理员"), (1, "普通用户")), default=1)
    last_login_time = models.DateTimeField("最后登录时间", null=True, blank=True)

    class Meta:
        db_table = 'common_account'
        verbose_name = '账户表'
        verbose_name_plural = verbose_name

    def __str__(self):
        return f"{self.username} ({self.mobile})" if self.mobile else self.username

    def set_password(self, raw_password):
        # self.password = make_password(raw_password)
        self.password = md5(raw_password)


class Token(BaseSortModel):
    name = models.CharField('名称', max_length=20, blank=True, null=True, default="")
    access_token = models.CharField("Access Token", max_length=512, blank=True, null=True, default="")
    allowed_ips = models.TextField("允许IP", default="*", help_text="逗号分隔的IP列表")
    description = models.TextField("用途说明", blank=True, default="")  # 记录Token用途
    expires_time = models.DateTimeField("过期时间", blank=True, null=True)  # 过期时间

    class Meta:
        db_table = 'common_token'
        verbose_name = 'API Token'
        verbose_name_plural = verbose_name

    def __str__(self):
        return f"{self.name} ({self.access_token[:10]}...)" if self.access_token else self.name

    def validate_allowed_ips(self, value):
        """验证IP格式（支持空值、*号、换行分隔的多IP）"""
        value = (value or "").strip()

        # 允许空值或通配符*
        if value in ("", "*"):
            return value

        # 按换行符分割并过滤空行
        ips = [ip.strip() for ip in value.split('\n') if ip.strip()]

        # 验证每个IP格式
        ipv4_pattern = r'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
        for ip in ips:
            if not re.match(ipv4_pattern, ip):
                raise serializers.ValidationError(f"无效的IPv4地址: {ip}")

        # 返回标准化格式（用换行符连接）
        return '\n'.join(ips)

    def save(self, *args, **kwargs):
        # 如果 token 为空或未设置，则自动生成
        if not self.access_token:
            # 生成唯一标识符（避免重复）
            unique_id = hashlib.sha256(
                f"{self.name}-{datetime.datetime.now().isoformat()}-{secrets.token_hex(4)}".encode()
            ).hexdigest()
            payload = {
                "sub": "third_party",  # 固定主题
                "jti": unique_id,  # 唯一标识符
                "name": self.name,  # 可读名称
                "usage": self.description,  # 用途说明
            }
            # 设置100年有效期（按天计算更直观）
            self.access_token = create_token(
                payload,
                timeout_hours=100 * 365 * 24  # 100年
            )
        super().save(*args, **kwargs)


class AccessLog(BaseModel):
    """系统访问日志（含IP定位信息）"""
    ip = models.CharField(max_length=50, verbose_name="访问IP")
    city = models.CharField(max_length=50, default="未知城市", verbose_name="访问城市")
    region = models.CharField(max_length=50, default="未知省份", verbose_name="访问省份")
    longitude = models.FloatField(null=True, blank=True, verbose_name="经度")
    latitude = models.FloatField(null=True, blank=True, verbose_name="纬度")
    access_time = models.DateTimeField(auto_now_add=True, verbose_name="访问时间")
    user_agent = models.TextField(null=True, blank=True, verbose_name="浏览器信息")

    class Meta:
        db_table = 'common_access_log'
        verbose_name = "访问日志"
        verbose_name_plural = "访问日志"
        ordering = ["-access_time"]
